package persistence;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import model.Prenda;
import model.Conjunto;

public class ConjuntoMapper extends ProductoMapper implements DataMapper<Conjunto> {
	private static ConjuntoMapper instance = null;
	
	private ConjuntoMapper() {}

	public static ConjuntoMapper getInstance() {
		if (instance == null) {
			instance = new ConjuntoMapper();
		}
		return instance;
	}
	
	@Override
	public boolean insertar(Conjunto conjunto) {
		boolean result = false;
		Connection connection = PoolConnection.getPoolConnection().getConnection();

		try {
			int productoId = getProximaClaveProducto();
			conjunto.setProductoId(productoId);
			
			String query = "INSERT INTO conjunto (producto_id, codigo, nombre, cantidad_stock, descuento) VALUES (?,?,?,?,?)";
			
			PreparedStatement ps = null;
			ps = connection.prepareStatement(query);
			ps.setInt(1, productoId);
			ps.setString(2, conjunto.getCodigo());
			ps.setString(3, conjunto.getNombre());
			ps.setInt(4, conjunto.getCantidadStock());
			ps.setInt(5, conjunto.getDescuento());
			ps.execute();
			
			for(Prenda prenda: conjunto.getPrendas()) {
				insertarConjuntoPrenda(connection, conjunto.getProductoId(), prenda);
			}
			
			PoolConnection.getPoolConnection().releaseConnection(connection);
			result = true;
		} catch (SQLException e) {
			PoolConnection.getPoolConnection().releaseConnection(connection);
			e.printStackTrace();
		}
		
		return result;
	}
	
	private void insertarConjuntoPrenda(Connection connection, long conjuntoId, Prenda prenda) throws SQLException {
		String query = "INSERT INTO conjunto_prenda (conjunto_id, prenda_id) VALUES (?,?)";
		PreparedStatement ps = null;
		ps = connection.prepareStatement(query);
		ps.setLong(1, conjuntoId);
		ps.setLong(2, prenda.getProductoId());
		ps.execute();
	}

	@Override
	public boolean modificar(Conjunto conjunto) {
		boolean result = false;
		Connection connection = PoolConnection.getPoolConnection().getConnection();

		try {
			//se eliminan todas las prendas asociadas para facilitar la actualizacion
			String query = "DELETE from conjunto_prenda where conjunto_id = ?";
			PreparedStatement ps = connection.prepareStatement(query);
			ps.setLong(1, conjunto.getProductoId());
			ps.execute();
			
			query = "UPDATE conjunto SET codigo = ?, nombre = ?, cantidad_stock = ?, descuento = ? where producto_id = ?";
			ps = connection.prepareStatement(query);
			ps.setString(1, conjunto.getCodigo());
			ps.setString(2, conjunto.getNombre());
			ps.setInt(3, conjunto.getCantidadStock());
			ps.setInt(4, conjunto.getDescuento());
			ps.setLong(5, conjunto.getProductoId());
			ps.execute();
			
			//se agregan todas las prendas asociadas
			for(Prenda prenda: conjunto.getPrendas()) {
				insertarConjuntoPrenda(connection, conjunto.getProductoId(), prenda);
			}
			
			PoolConnection.getPoolConnection().releaseConnection(connection);
			result = true;
		} catch (SQLException e) {
			PoolConnection.getPoolConnection().releaseConnection(connection);
			e.printStackTrace();
		}
		
		return result;
	}

	@Override
	public boolean eliminar(Conjunto conjunto) {
		boolean result = false;
		Connection con = PoolConnection.getPoolConnection().getConnection();

		try {
			String query = "UPDATE conjunto_prenda set is_vigente = 1 where conjunto_id = ?";
			PreparedStatement ps = con.prepareStatement(query);
			ps.setLong(1, conjunto.getProductoId());
			ps.execute();
			
			PoolConnection.getPoolConnection().releaseConnection(con);
			result = true;
		} catch (SQLException e) {
			System.out.println("Mensaje Error al Eliminar Conjunto: " + e.getMessage());
			System.out.println("Stack Trace al Eliminar Conjunto: " + e.getStackTrace());
			PoolConnection.getPoolConnection().releaseConnection(con);
		}
		
		return result;
	}

	@Override
	public Conjunto buscar(Long conjuntoId) {
		Conjunto conjunto = null;
		Connection con = PoolConnection.getPoolConnection().getConnection();

		try {
			String query = "SELECT * from conjunto where producto_id = ? and is_vigente = 1";
			PreparedStatement ps = null;
			ps = con.prepareStatement(query);
			ps.setLong(1, conjuntoId);
			ResultSet result = ps.executeQuery();
			
			if(result.next()) {
				conjunto = new Conjunto(result.getString("codigo"),result.getString("nombre"), result.getInt("cantidad_stock"), result.getInt("descuento"));
				conjunto.setProductoId(result.getLong("producto_id"));
				
				List<Prenda> prendas = buscarPrendasEnConjunto(con, conjunto);
				conjunto.setPrendas(prendas);
			}
			
			PoolConnection.getPoolConnection().releaseConnection(con);

		} catch (SQLException e) {
			System.out.println("Mensaje Error al buscar Conjunto: " + e.getMessage());
			System.out.println("Stack Trace al buscar Conjunto: " + e.getStackTrace());
			PoolConnection.getPoolConnection().releaseConnection(con);
		}
		return conjunto;
	}
	
	private List<Prenda> buscarPrendasEnConjunto(Connection connection, Conjunto conjunto) throws SQLException {
		List<Prenda> prendas = new ArrayList<Prenda>();
		
		String query = "SELECT * from conjunto_prenda where conjunto_id = ?";
		PreparedStatement ps = null;
		ps = connection.prepareStatement(query);
		ps.setLong(1, conjunto.getProductoId());
		ResultSet result = ps.executeQuery();
		
		while(result.next()) {
			Prenda prenda = ProductoMapper.getInstance().buscarPrenda(result.getLong("prenda_id"));
			if(prenda != null) {
				prendas.add(prenda);
			}
			
		}
		
		return prendas;
	}

	@Override
	public List<Conjunto> buscarTodos() {
		List<Conjunto> conjuntos = new ArrayList<Conjunto>();
		Connection con = PoolConnection.getPoolConnection().getConnection();

		try {
			String query = "SELECT * from conjunto where is_vigente = 1";
			PreparedStatement ps = null;
			ps = con.prepareStatement(query);

			ResultSet result = ps.executeQuery();
			while(result.next()) {
				Conjunto conjunto = new Conjunto(result.getString("codigo"),result.getString("nombre"), result.getInt("cantidad_stock"), result.getInt("descuento"));
				conjunto.setProductoId(result.getLong("producto_id"));
				
				List<Prenda> prendas = buscarPrendasEnConjunto(con, conjunto);
				conjunto.setPrendas(prendas);

				conjuntos.add(conjunto);
			}
			PoolConnection.getPoolConnection().releaseConnection(con);

		} catch (SQLException e) {
			System.out.println("Mensaje Error Buscar todos los Conjuntos: " + e.getMessage());
			System.out.println("Stack Trace al Buscar todos los Conjuntos: " + e.getStackTrace());
			PoolConnection.getPoolConnection().releaseConnection(con);
		}
		return conjuntos;
	}
	
	public boolean actualizarStock(Conjunto conjunto, int cantidadVendida) {
		boolean result = false;
		Connection con = PoolConnection.getPoolConnection().getConnection();

		try {
			String query = "UPDATE conjunto set cantidad_stock = ? where producto_id = ?";
			PreparedStatement ps = con.prepareStatement(query);
			int stock = conjunto.getCantidadStock() - cantidadVendida;
			ps.setInt(1, stock);
			ps.setLong(2, conjunto.getProductoId());
			ps.execute();
			
			PoolConnection.getPoolConnection().releaseConnection(con);
			result = true;
		} catch (SQLException e) {
			System.out.println("Mensaje Error al actualizar stock Conjunto: " + e.getMessage());
			System.out.println("Stack Trace al actualizar stock Conjunto: " + e.getStackTrace());
			PoolConnection.getPoolConnection().releaseConnection(con);
		}
		
		return result;
	}
	
	

}